Imports System.Drawing
Imports System.Drawing.Imaging


Public Class MagnifierForm
    Inherits System.Windows.Forms.Form

    'dwRop Constants
    Public Const BLACKNESS = &H42
    Public Const DSTINVERT = &H550009
    Public Const CAPTUREBLT = &H40000000
    Public Const MERGECOPY = &HC000CA
    Public Const MERGEPAINT = &HBB0226
    Public Const NOMIRRORBITMAP = &H80000000
    Public Const NOTSRCCOPY = &H330008
    Public Const NOTSRCERASE = &H1100A6
    Public Const PATCOPY = &HF00021
    Public Const PATINVERT = &H5A0049
    Public Const PATPAINT = &HFB0A09
    Public Const SRCCOPY = &HCC0020
    Public Const SRCAND = &H8800C6
    Public Const SRCERASE = &H440328
    Public Const SRCINVERT = &H660046
    Public Const SRCPAINT = &HEE0086
    Public Const WHITENESS = &HFF0062

    Public Declare Function BitBlt Lib "gdi32" Alias "BitBlt" (ByVal hDestDC As Integer, ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hSrcDC As Integer, ByVal xSrc As Integer, ByVal ySrc As Integer, ByVal dwRop As Integer) As Integer
    Public Declare Function GetDesktopWindow Lib "user32" () As IntPtr
    Public Declare Function GetDC Lib "user32.dll" (ByVal hWnd As IntPtr) As IntPtr
    Public Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Integer, ByVal hdc As Integer) As Integer

    Dim GrayscaleMatrix As Imaging.ColorMatrix = New Imaging.ColorMatrix(New Single()() _
              {New Single() {0.3, 0.3, 0.3, 0, 0}, _
               New Single() {0.59, 0.59, 0.59, 0, 0}, _
               New Single() {0.11, 0.11, 0.11, 0, 0}, _
               New Single() {0, 0, 0, 1, 0}, _
               New Single() {0, 0, 0, 0, 1}})
    Friend WithEvents ContextMenuStrip1 As System.Windows.Forms.ContextMenuStrip
    Friend WithEvents itmNormal As System.Windows.Forms.ToolStripMenuItem
    Friend WithEvents ItmGrayscale As System.Windows.Forms.ToolStripMenuItem
    Friend WithEvents ITMInvertColors As System.Windows.Forms.ToolStripMenuItem
    Friend WithEvents ToolStripSeparator1 As System.Windows.Forms.ToolStripSeparator
    Friend WithEvents CloseToolStripMenuItem As System.Windows.Forms.ToolStripMenuItem
    Dim ImageAttributes As New Drawing.Imaging.ImageAttributes

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

        'Double Buffering
        Me.SetStyle(Windows.Forms.ControlStyles.DoubleBuffer Or Windows.Forms.ControlStyles.UserPaint Or Windows.Forms.ControlStyles.AllPaintingInWmPaint, True)
        Me.UpdateStyles()

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Friend WithEvents stbMagnifier As System.Windows.Forms.StatusBar
    Friend WithEvents vsbMagnifier As System.Windows.Forms.VScrollBar
    Friend WithEvents tmrUpdate As System.Windows.Forms.Timer
    Friend WithEvents tmrRepaint As System.Windows.Forms.Timer
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.components = New System.ComponentModel.Container
        Me.stbMagnifier = New System.Windows.Forms.StatusBar
        Me.vsbMagnifier = New System.Windows.Forms.VScrollBar
        Me.tmrRepaint = New System.Windows.Forms.Timer(Me.components)
        Me.tmrUpdate = New System.Windows.Forms.Timer(Me.components)
        Me.ContextMenuStrip1 = New System.Windows.Forms.ContextMenuStrip(Me.components)
        Me.itmNormal = New System.Windows.Forms.ToolStripMenuItem
        Me.ItmGrayscale = New System.Windows.Forms.ToolStripMenuItem
        Me.ITMInvertColors = New System.Windows.Forms.ToolStripMenuItem
        Me.ToolStripSeparator1 = New System.Windows.Forms.ToolStripSeparator
        Me.CloseToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem
        Me.ContextMenuStrip1.SuspendLayout()
        Me.SuspendLayout()
        '
        'stbMagnifier
        '
        Me.stbMagnifier.Location = New System.Drawing.Point(0, 248)
        Me.stbMagnifier.Name = "stbMagnifier"
        Me.stbMagnifier.Size = New System.Drawing.Size(292, 25)
        Me.stbMagnifier.TabIndex = 0
        '
        'vsbMagnifier
        '
        Me.vsbMagnifier.Dock = System.Windows.Forms.DockStyle.Right
        Me.vsbMagnifier.LargeChange = 1
        Me.vsbMagnifier.Location = New System.Drawing.Point(276, 0)
        Me.vsbMagnifier.Minimum = 1
        Me.vsbMagnifier.Name = "vsbMagnifier"
        Me.vsbMagnifier.Size = New System.Drawing.Size(16, 248)
        Me.vsbMagnifier.TabIndex = 1
        Me.vsbMagnifier.Value = 50
        '
        'tmrRepaint
        '
        Me.tmrRepaint.Enabled = True
        '
        'ContextMenuStrip1
        '
        Me.ContextMenuStrip1.BindingContext = Nothing
        Me.ContextMenuStrip1.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.itmNormal, Me.ItmGrayscale, Me.ITMInvertColors, Me.ToolStripSeparator1, Me.CloseToolStripMenuItem})
        Me.ContextMenuStrip1.Name = "ContextMenuStrip1"
        Me.ContextMenuStrip1.Region = Nothing
        Me.ContextMenuStrip1.Size = New System.Drawing.Size(126, 98)
        '
        'itmNormal
        '
        Me.itmNormal.Checked = True
        Me.itmNormal.CheckOnClick = True
        Me.itmNormal.CheckState = System.Windows.Forms.CheckState.Checked
        Me.itmNormal.Name = "itmNormal"
        Me.itmNormal.Size = New System.Drawing.Size(125, 22)
        Me.itmNormal.Text = "&Normal"
        '
        'ItmGrayscale
        '
        Me.ItmGrayscale.CheckOnClick = True
        Me.ItmGrayscale.Name = "ItmGrayscale"
        Me.ItmGrayscale.Size = New System.Drawing.Size(125, 22)
        Me.ItmGrayscale.Text = "&GrayScale"
        '
        'ITMInvertColors
        '
        Me.ITMInvertColors.CheckOnClick = True
        Me.ITMInvertColors.Name = "ITMInvertColors"
        Me.ITMInvertColors.Size = New System.Drawing.Size(125, 22)
        Me.ITMInvertColors.Text = "&Invert"
        '
        'ToolStripSeparator1
        '
        Me.ToolStripSeparator1.Name = "ToolStripSeparator1"
        Me.ToolStripSeparator1.Size = New System.Drawing.Size(122, 6)
        '
        'CloseToolStripMenuItem
        '
        Me.CloseToolStripMenuItem.Name = "CloseToolStripMenuItem"
        Me.CloseToolStripMenuItem.Size = New System.Drawing.Size(125, 22)
        Me.CloseToolStripMenuItem.Text = "&Close"
        '
        'MagnifierForm
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 15)
        Me.ClientSize = New System.Drawing.Size(292, 273)
        Me.ContextMenuStrip = Me.ContextMenuStrip1
        Me.ControlBox = False
        Me.Controls.Add(Me.vsbMagnifier)
        Me.Controls.Add(Me.stbMagnifier)
        Me.DoubleBuffered = True
        Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow
        Me.MaximizeBox = False
        Me.MinimizeBox = False
        Me.Name = "MagnifierForm"
        Me.ShowIcon = False
        Me.ShowInTaskbar = False
        Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
        Me.Text = " "
        Me.TopMost = True
        Me.ContextMenuStrip1.ResumeLayout(False)
        Me.ResumeLayout(False)

    End Sub

#End Region

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Initialize Greyscale Matrix
        ImageAttributes.SetColorMatrix(GrayscaleMatrix)
    End Sub

    'Timer use to repaint magnifier with the set time interval or refresh rate
    Private Sub tmrRepaint_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrRepaint.Tick
        RepaintMagnifier()
    End Sub

    'By using a seperate function to repaint the screen magnifier program
    'it will help prevent flickering from happening.
    'using Invalidate will cause flickering.
    'Thanks for Dr. ScrewUp for this solution!!
    Private Sub RepaintMagnifier()
        Dim e As Graphics = Me.CreateGraphics
        Dim hr As Integer = Windows.Forms.Screen.PrimaryScreen.Bounds.Width
        Dim vr As Integer = Windows.Forms.Screen.PrimaryScreen.Bounds.Height

        'Get Zoom Percentage
        Dim percent As Single = Me.vsbMagnifier.Value / 100
        Dim lengthX As Single = (Me.Width - Me.vsbMagnifier.Width) * percent
        Dim lengthY As Single = (Me.Height - Me.stbMagnifier.Height) * percent

        'Zoom Factor To Statusbar
        Me.stbMagnifier.Text = "Zoom Factor : " & 100 - Me.vsbMagnifier.Value & " X"

        'Center Image Around The Mouse
        Dim offsetX As Single = lengthX \ 2
        Dim offsetY As Single = lengthY \ 2

        'Actual Area To Blit To
        Dim blitAreaX As Integer = Me.Width - Me.vsbMagnifier.Width
        Dim blitAreaY As Integer = Me.Height - Me.stbMagnifier.Height

        'New Bitmap & Graphics Object
        Dim b As New Bitmap(CInt(blitAreaX), CInt(blitAreaY))
        Dim g As Graphics = Graphics.FromImage(b)

        'Try to make things faster
        g.SmoothingMode = Drawing2D.SmoothingMode.HighSpeed
        g.CompositingQuality = Drawing2D.CompositingQuality.HighSpeed
        g.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighSpeed
        g.InterpolationMode = Drawing2D.InterpolationMode.Low

        'Try to make things faster
        e.SmoothingMode = Drawing2D.SmoothingMode.HighSpeed
        e.CompositingQuality = Drawing2D.CompositingQuality.HighSpeed
        e.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighSpeed
        e.InterpolationMode = Drawing2D.InterpolationMode.Low

        'DC Of Desktop And Graphics Object
        Dim hWndWindow As IntPtr = GetDesktopWindow()
        Dim hdcWindow As IntPtr = GetDC(hWndWindow)
        Dim hdcGraphics As IntPtr = g.GetHdc()

        'BitBlt & Graphics.DrawImage Solution
        '------------------------------------------

        'BitBlt the Screen (Captures Transparent Windows & Prevents Mirror Effect)
        BitBlt(hdcGraphics.ToInt32, 0, 0, blitAreaX, blitAreaY, hdcWindow.ToInt32, Windows.Forms.Cursor.Position.X - offsetX, Windows.Forms.Cursor.Position.Y - offsetY, SRCCOPY Or CAPTUREBLT Or NOMIRRORBITMAP)

        'BitBlt to Invert Colors
        If Me.ITMInvertColors.Checked = True Then
            BitBlt(hdcGraphics.ToInt32, 0, 0, blitAreaX, blitAreaY, hdcGraphics.ToInt32, 0, 0, NOTSRCCOPY)
        End If

        'Free Memory
        ReleaseDC(hWndWindow.ToInt32, hdcWindow.ToInt32)
        g.ReleaseHdc(hdcGraphics)

        If Me.itmNormal.Checked = True Or Me.ITMInvertColors.Checked = True Then
            e.DrawImage(b, New Drawing.Rectangle(0, 0, blitAreaX, blitAreaY), 0, 0, lengthX, lengthY, GraphicsUnit.Pixel)
        ElseIf Me.ItmGrayscale.Checked = True Then 'DrawImage w/ Grayscale ImageAttributes
            e.DrawImage(b, New Drawing.Rectangle(0, 0, blitAreaX, blitAreaY), 0, 0, lengthX, lengthY, GraphicsUnit.Pixel, ImageAttributes)
        End If

        e.Dispose()
    End Sub
    Private Sub CloseToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CloseToolStripMenuItem.Click
        Me.Close()
    End Sub

    Private Sub ItmGrayscale_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ItmGrayscale.Click
        itmNormal.Checked = False
        ITMInvertColors.Checked = False
    End Sub

    Private Sub ITMInvertColors_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ITMInvertColors.Click
        ItmGrayscale.Checked = False
        itmNormal.Checked = False
    End Sub

    Private Sub itmNormal_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles itmNormal.Click
        ItmGrayscale.Checked = False
        ITMInvertColors.Checked = False
    End Sub
End Class
